// Device_P3Ks.h: interface for the Device_P3Ks class.
//
//////////////////////////////////////////////////////////////////////
#ifndef __Device_P3Ks_H__
#define __Device_P3Ks_H__

#include "VDevicePhone.h"
#include "_LCDScreen.h"
#include "_ToneGenerator.h"
#include "_LEDFlash.h"

#define IS_OLD_LAYOUT(wVer) ((wVer) >= 0x0200 && (wVer) < 0x0300 || IS_P9K(wVer))
#define HAS_AUDIO_DECT(wVer) (FALSE)

class Device_P3Ks;
typedef _LCDScreen<Device_P3Ks, 0x04, _LCDDesc>			_P3K_LCD;
typedef _ToneGenerator<Device_P3Ks>						_P3K_ToneGenerator;
typedef _WaveRing<Device_P3Ks>							_P3K_WaveRing;
typedef _AudioName<Device_P3Ks, 0x82>					_P3K_AudioName;
typedef _LEDControl<Device_P3Ks, 0x12>					_P3K_GroundLED;

class Device_P3Ks : public _VDevicePhone16
	, public _P3K_ToneGenerator
	, public _P3K_WaveRing
	, public _P3K_LCD
	, public _P3K_GroundLED
	, public _P3K_AudioName
{
	BEGIN_MSG_MAP(Device_P3Ks)
		MESSAGE_RANGE_HANDLER(CMD_DEV_CONTROL_FIRST, CMD_DEV_CONTROL_LAST, OnDeviceControl)
		CHAIN_MSG_MAP(_P3K_ToneGenerator)
		CHAIN_MSG_MAP(_P3K_WaveRing)
		CHAIN_MSG_MAP(_P3K_LCD)
		CHAIN_MSG_MAP(_P3K_GroundLED)
//		CHAIN_MSG_MAP(_P3K_AudioName)
		CHAIN_MSG_MAP(_VDevicePhone16)
	END_MSG_MAP()
public:

	virtual BOOL _AfterDeviceOpen();
	virtual BOOL _BeforeDeviceClose();
	virtual void _AfterDeviceLose();
	virtual BOOL _Pulsation();
	virtual void TraceSendData(USBTEL_COMM_16& rTraceData);
	virtual void TraceReadData(USBTEL_COMM_16& rTraceData);

protected:
	BOOL GetKeyEvent();
	BOOL GetForkEvent();
	BOOL OnDeviceKeyEvent(WPARAM wParam, LPARAM lParam);

public:
	Device_P3Ks()
	{
		m_lpszExpectProductName = _T("VOIP USB Phone"); 
	}
	~Device_P3Ks()
	{
	}
private:
	struct P3K_LOGIC_FLAG
	{
		BYTE bRingingFlag:1;
		BYTE bForkDown:1;
		BYTE bLastKey;
	}m_vLogicFlags;

private:
	void InitKeypadLayoutByVersion(WORD wVer)
	{
		ClearKeypadLayout();
		if(IS_OLD_LAYOUT(wVer))
		{
			DefineKeypad(0x21,'1');
			DefineKeypad(0x11,'2');
			DefineKeypad(0x01,'3');
			DefineKeypad(0x22,'4');
			DefineKeypad(0x12,'5');
			DefineKeypad(0x02,'6');
			DefineKeypad(0x23,'7');
			DefineKeypad(0x13,'8');
			DefineKeypad(0x03,'9');
			DefineKeypad(0x24,'*');
			DefineKeypad(0x14,'0');
			DefineKeypad(0x04,'#');
			DefineKeypad(0x34,USB_KEY_IN);
			DefineKeypad(0x10,USB_KEY_OUT);
			DefineKeypad(0x32,USB_KEY_UP);
			DefineKeypad(0x30,USB_KEY_DOWN);
			DefineKeypad(0x31,USB_KEY_V_INC);
			DefineKeypad(0x40,USB_KEY_V_DEC);

			DefineKeypad(0x33,USB_KEY_C);
			DefineKeypad(0x00,USB_KEY_SEND);
			DefineKeypad(0x05,USB_KEY_HELP);
			DefineKeypad(0x15,USB_KEY_FLASH);
			DefineKeypad(0x44,USB_KEY_REDIAL);
			DefineKeypad(0x25,USB_KEY_SEND);
			DefineKeypad(0x20,USB_KEY_HANDFREE);

			// P9K
			DefineKeypad(0x16,USB_KEY_HOLD);
			DefineKeypad(0x26,USB_KEY_RING);
			DefineKeypad(0x36,USB_KEY_HEADSET);
		}
		else
		{
			DefineKeypad(0x21, '1');
			DefineKeypad(0x11, '2');
			DefineKeypad(0x01, '3');
			DefineKeypad(0x22, '4');
			DefineKeypad(0x12, '5');
			DefineKeypad(0x02, '6');
			DefineKeypad(0x23, '7');
			DefineKeypad(0x13, '8');
			DefineKeypad(0x03, '9');
			DefineKeypad(0x24, '*');
			DefineKeypad(0x14, '0');
			DefineKeypad(0x04, '#');
			DefineKeypad(0x34, USB_KEY_CONTACTS);
			DefineKeypad(0x10, USB_KEY_VIDEO);
			DefineKeypad(0x32, USB_KEY_UP);
			DefineKeypad(0x30, USB_KEY_DOWN);
			DefineKeypad(0x31, USB_KEY_CALLS);
			DefineKeypad(0x40, USB_KEY_C);

			DefineKeypad(0x33, USB_KEY_V_INC);
			DefineKeypad(0x00, USB_KEY_V_DEC);
			DefineKeypad(0x05, USB_KEY_MUTE);
			DefineKeypad(0x15, USB_KEY_HOLD);
			DefineKeypad(0x44, USB_KEY_SEND);
			DefineKeypad(0x25, USB_KEY_RING);
			DefineKeypad(0x20, USB_KEY_HANDFREE);
		}
	}
	LRESULT OnDeviceControl(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		switch(uMsg)
		{
		case CMD_DEV_IO_SPK:
			PhoneInOneByteCommand(0x0C, wParam != 0);
			break;
		case CMD_DEV_IO_MIC:
			PhoneInOneByteCommand( 0x02, wParam != 0);
			break;
		case CMD_DEV_PLAY_TONE:
			//SYZ_TRACE1("<=> %s Dial Tone.", TONE_DIAL == wParam ? _T("Turn-on") : _T("Turn-off"));
			PhoneInOneByteCommand(0x09, TONE_DIAL == wParam);
			if(TONE_DIAL == wParam)
				_P3K_ToneGenerator::PlayTone(TONE_SILENCE);
			else
				_P3K_ToneGenerator::PlayTone((TONE_TYPE)wParam);
			break;
		case CMD_DEV_GET_AUDIO_NAME:
			if(HAS_AUDIO_DECT(m_wProductVersion))
				return _P3K_AudioName::OnDeviceControl(uMsg, wParam, lParam, bHandled);
			else
				return _VDevicePhone16::OnDeviceControl(uMsg, wParam, lParam, bHandled);
		case CMD_DEV_SET_HEADSET_LED:
			PhoneInOneByteCommand(0x08, wParam != 0);
			break;
		case CMD_DEV_SET_INUSE_LED:
			PhoneInOneByteCommand(0x0b, wParam != 0);
			break;
		case CMD_DEV_SET_SPEAK_LED:
			PhoneInOneByteCommand(0x0d, wParam != 0);
			break;

		default:
			bHandled = FALSE;
		}
		return 0;
	}
};


#endif //__Device_P3Ks_H__